package per.jdz.demo.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import per.jdz.demo.config.FilePathConfigProperty;
import per.jdz.demo.dao.OriginHouseDataMapper;
import per.jdz.demo.domain.dto.CommonLDTO;
import per.jdz.demo.domain.dto.HouseDTO;
import per.jdz.demo.domain.entity.OriginHouseData;
import per.jdz.demo.domain.entity.RenameHouse;
import per.jdz.demo.readlistener.GenericReadListener;
import per.jdz.demo.service.DouBaoService;
import per.jdz.demo.service.OriginHouseDataService;
import per.jdz.demo.service.ProcessFileService;
import per.jdz.demo.service.RenameHouseService;
import per.jdz.demo.utils.FileUtil;
import per.jdz.demo.utils.StrUtil;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;

import static per.jdz.demo.domain.entity.table.OriginHouseDataTableDef.ORIGIN_HOUSE_DATA;
import static per.jdz.demo.domain.entity.table.RenameHouseTableDef.RENAME_HOUSE;


/**
 * @author Jdz
 * @date 2025/1/6
 */
@Service
@Slf4j
public class OriginHouseDataServiceImpl extends ServiceImpl<OriginHouseDataMapper, OriginHouseData> implements OriginHouseDataService, ProcessFileService {
    @Resource
    private FilePathConfigProperty filePathConfigProperty;

    @Resource
    private OriginHouseDataMapper originHouseDataMapper;

    @Resource
    private RenameHouseService renameHouseService;

    @Resource
    private DouBaoService douBaoService;

    @Resource(name = "threadPoolTaskExecutor")
    private ThreadPoolTaskExecutor executor;

    @Override
    public void insertData(GenericReadListener.BatchProcessor batchProcessor) {
        FileUtil.insertData(filePathConfigProperty.getSplit(), OriginHouseData.class, batchProcessor);
    }

    @Override
    public String splitFile() {
        return FileUtil.splitFile(filePathConfigProperty.getOriginFileDir(), filePathConfigProperty.getSplit(), OriginHouseData.class);
    }

    @Override
    public void distinctData() {
        originHouseDataMapper.distinctData();
    }

    @Override
    public void syncData() {
        // 插入新增数据
        originHouseDataMapper.insertHouseData();
        // 删除重复数据
        originHouseDataMapper.deleteHouseData();
        originHouseDataMapper.insertRenameHouseData();
    }

    @Override
    public void matchCommonId() {
        setCommonId();
    }

    @Override
    public void updateHouseDataByRenameData() {
        originHouseDataMapper.updateHouseData();
    }

    @Override
    public void rename() {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(RENAME_HOUSE.COMMON_ID.isNull());
        List<RenameHouse> list = renameHouseService.list(queryWrapper);
        log.info("list size:{}", list.size());
        list.forEach(renameHouse -> {
            if (renameHouse.getRenameProjectName() != null && !containsProjectKeywords(renameHouse.getRenameProjectName())) return;
            QueryWrapper query = QueryWrapper.create().where(ORIGIN_HOUSE_DATA.RENAME_HASH_VALUE.eq(renameHouse.getRenameHashValue()));
            List<OriginHouseData> originHouseDataList = originHouseDataMapper.selectListByQuery(query);
            HashMap<String, String> developerMap = new HashMap<>();
            HashMap<String, String> preSaleLicenseNumberMap = new HashMap<>();
            originHouseDataList.forEach(originHouseData -> {
                developerMap.put(originHouseData.getDeveloper(), "");
                preSaleLicenseNumberMap.put(originHouseData.getPreSaleLicenseNumber(), "");
            });

            // 合并键并转换为逗号分隔的字符串
            String developerKeys = String.join(",",
                    new ArrayList<>(developerMap.keySet()));
            String preSaleLicenseNumberKeys = String.join(",",
                    new ArrayList<>(preSaleLicenseNumberMap.keySet()));
            if (renameHouse.getRenameProjectName() == null) {
                if (containsProjectKeywords(renameHouse.getProjectName())) {
                    HouseDTO houseDTO = createHouseDTO(renameHouse, developerKeys, preSaleLicenseNumberKeys);
                    String projectName = douBaoService.getProjectName(houseDTO);
                    renameHouse.setRenameProjectName(projectName);
                } else {
                    renameHouse.setRenameProjectName(renameHouse.getProjectName());
                }
            } else {
                if (containsProjectKeywords(renameHouse.getRenameProjectName())) {
                    HouseDTO houseDTO = createHouseDTO(renameHouse, developerKeys, preSaleLicenseNumberKeys);
                    String projectName = douBaoService.getProjectName(houseDTO);
                    renameHouse.setRenameProjectName(projectName);
                }
            }
            renameHouseService.updateById(renameHouse);
        });
    }

    public void setCommonId() {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(RENAME_HOUSE.ID,
                        RENAME_HOUSE.RENAME_PROJECT_NAME)
                .where(RENAME_HOUSE.COMMON_ID.isNull());
        List<RenameHouse> list = renameHouseService.list(queryWrapper);
        List<CommonLDTO> commonDTOList = renameHouseService.getCommonList();
        AtomicBoolean flag = new AtomicBoolean(false);
        CompletableFuture<?>[] futures = list.stream().map(hd -> CompletableFuture.runAsync(() -> {
            try {
                for (CommonLDTO common : commonDTOList) {
                    if (common.getName() == null) continue;
                    double percentage = StrUtil.getSimilar(common.getName().replace("济南", ""), hd.getRenameProjectName().replace("济南", ""));
//                    log.info("{}", percentage);
                    if (percentage > 0.4) log.info("{}-{}-{}", common.getName(), hd.getRenameProjectName(), percentage);
                    if (percentage < 0.55) return;
                    if (hd.getSimilarDegree() != null) {
                        if (hd.getSimilarDegree() > percentage) {
                            return;
                        }
                    }
                    hd.setSimilarDegree(percentage);
                    hd.setCommonId(common.getId());
                    flag.set(true);
                }

            } catch (Exception e) {
                // Log the exception or handle it as appropriate for your application
                log.error("Error processing data for project: " + hd, e);
                throw e; // Rethrow to ensure the future is marked as exceptionally completed
            }
        }, executor).handle((result, throwable) -> {
            if (throwable != null) {
                // Handle or log the exception here
                log.error("{}", hd);
                log.error("Exception occurred while processing data asynchronously", throwable);
            }
            return result;
        })).toArray(CompletableFuture<?>[]::new);
        CompletableFuture.allOf(futures).join();
        if (flag.get()) {
            renameHouseService.updateBatch(list);
        }
    }

    private HouseDTO createHouseDTO(RenameHouse renameHouse, String developerKeys, String preSaleLicenseNumberKeys) {
        HouseDTO houseDTO = new HouseDTO();
        houseDTO.setProjectName(renameHouse.getProjectName());
        houseDTO.setProjectAddress(renameHouse.getProjectAddress());
        houseDTO.setDeveloper(developerKeys);
        houseDTO.setPreSaleLicenseNumber(preSaleLicenseNumberKeys);
        return houseDTO;
    }

    private boolean containsProjectKeywords(String projectName) {
        // 使用正则表达式来简化多个 contains 检查
        return projectName.matches(".*(?:项目|地块|未找到|明确|目前|信息|匹配|工程|可能|期|资料|抱歉|组团|情况|#).*");
    }
}
